<template>
  <div class="app">
    <h1>reactive() 的局限性</h1>
    <div><button @click="changeUser">改变user的值,看看是否会丢失响应式</button></div>
    <ul>
      <li>user:{{ user.name }}--{{ user.age }}--{{ user.sex }}</li>
      <li>--------</li>
      <li v-for="item in user.aihao" :key="item">{{ item }}</li>
    </ul>
    <hr />
    <button @click="changeUserJie">改变user结构后的值,看看是否会丢失响应式</button>
    <ul>
      <li>name:{{ name }}</li>
      <li>age:{{ age }}</li>
      <li>sex:{{ sex }}</li>
      <li>----------</li>
      <li v-for="item in aihao" :key="item">{{ item }}</li>
      <li>-------</li>
      <li v-for="item in shenAihao" :key="item">{{ item }}</li>

      <li>-------</li>
      <li v-for="item in reactShenAihao" :key="item">{{ item }}</li>
    </ul>
  </div>
</template>

<script setup lang="ts" name="Study3StuDemo3">
import { reactive } from 'vue'

// 1.有限的值类型：它只能用于对象类型 (对象、数组和如 Map、Set 这样的集合类型)。它不能持有如 string、number 或 boolean 这样的原始类型。
// let state1 = reactive(3) // 报错

// 2.不能替换整个对象：由于 Vue 的响应式跟踪是通过属性访问实现的，因此我们必须始终保持对响应式对象的相同引用。
// 这意味着我们不能轻易地“替换”响应式对象，因为这样的话与第一个引用的响应性连接将丢失：
// 参考 Study3StuDemo1的案例

// 3.对解构操作不友好：
// 3-1 当我们将响应式对象的`原始类型`属性解构为本地变量时，将丢失响应性连接,应用类型保留响应式

let user = reactive({
  name: '张国荣',
  sex: 'man',
  age: 18,
  aihao: ['唱', '跳', 'rap', '篮球']
})
let { name, sex, age, aihao } = user
// 把aihao深拷贝
let shenAihao = JSON.parse(JSON.stringify(aihao))
// 再把深拷贝的aihao变为reactive响应式数据
let reactShenAihao = reactive(JSON.parse(JSON.stringify(aihao)))
function changeUser() {
  user.age = 88
  user.aihao.push('坤坤')
}

function changeUserJie() {
  // 原始类型丢失响应式
  // name = '周杰伦'

  // 引用类型不会丢失响应性，但是引用的还是原来的地址，会干扰解构之前的对象属性
  // aihao.push('Music~!')

  // 深copy并且从新包装的对象
  reactShenAihao.push('爱好者！')
  console.log(reactShenAihao)
}
</script>

<style scoped></style>
